import json
from fastapi import APIRouter, HTTPException, Depends, Query
from sqlalchemy.orm import Session
from sqlalchemy import func
from typing import Dict, Any

from common.database import get_db, LaixinRecord, get_storage_adapter

# 创建路由器
router = APIRouter(prefix="/letter/api", tags=["来信件监控和性能"])

# 全局变量，需要在主应用中初始化
CALL_RECORDS = {}
thread_pool = None


def set_global_variables(_call_records, _thread_pool):
    """设置全局变量，由主应用调用"""
    global CALL_RECORDS, thread_pool
    CALL_RECORDS = _call_records
    thread_pool = _thread_pool


@router.get("/calls")
async def get_call_logs(
    db: Session = Depends(get_db),
    date: str = Query(None, description="查询日期，格式YYYY-MM-DD"),
    bh: str = Query(None, description="信访件编号"),
    status: str = Query(None, description="查询状态，成功或失败"),
    txm: str = Query(None, description="条形码"),
):
    """
    获取来信件API调用日志列表。
    """
    try:
        # 检查是否使用数据库存储
        if db is not None:
            # 使用数据库查询
            query = db.query(LaixinRecord).filter(
                LaixinRecord.is_delete == 0
            )  # 只查询未删除的数据

            if date:
                # 根据日期过滤，这里假设日期格式为 'YYYY-MM-DD'
                query = query.filter(func.DATE(LaixinRecord.start_time) == date)

            if bh:
                query = query.filter(LaixinRecord.bh.ilike(f"%{bh}%"))  # 模糊匹配

            if status:
                query = query.filter(LaixinRecord.status == status)

            # 按照开始时间降序排序
            filtered_records = query.order_by(LaixinRecord.start_time.desc()).all()

            # 如果指定了txm参数，在内存中进行过滤
            if txm:
                filtered_records = [
                    record
                    for record in filtered_records
                    if record.response and txm in record.response
                ]
        else:
            # 使用存储适配器查询
            storage = get_storage_adapter()
            filters = {}
            if date:
                filters['date'] = date
            if bh:
                filters['bh'] = bh
            if status:
                filters['status'] = status
            if txm:
                filters['txm'] = txm
            
            filtered_records = storage.get_laixin_records(filters)

        # 格式化数据以匹配原有的API响应格式
        formatted_calls = []
        for record in filtered_records:
            # 处理不同的记录类型（数据库对象或字典）
            if hasattr(record, 'process_time'):
                # 数据库对象
                process_time_float = float(record.process_time) if record.process_time is not None else 0.0
                bh = record.bh
                start_time = record.start_time
                status = record.status
                case_instruction = record.case_instruction
                response = record.response
                error_info = record.error_info
                txm = getattr(record, 'txm', None)
            else:
                # 字典对象（内存存储）
                process_time_float = float(record.get('process_time', 0.0))
                bh = record.get('bh')
                start_time = record.get('start_time')
                status = record.get('status')
                case_instruction = record.get('case_instruction')
                response = record.get('response')
                error_info = record.get('error_info')
                txm = record.get('txm')
            
            # 解析响应，提取 txm 以便前端直接展示
            _resp_obj = json.loads(response) if response else None
            _txm_value = txm
            if _resp_obj and not _txm_value:
                _txm_value = _resp_obj.get("txm") or (
                    _resp_obj.get("data", {})
                    if isinstance(_resp_obj.get("data", {}), dict)
                    else {}
                ).get("txm")

            formatted_calls.append(
                {
                    "bh": bh,
                    "startTime": start_time.strftime("%Y-%m-%d %H:%M:%S") if hasattr(start_time, 'strftime') else start_time,
                    "status": status,
                    "processTime": process_time_float,
                    "txm": _txm_value,
                    # 在请求信息里补充 txm，便于前端展示条形码
                    "requestInfo": {
                        "caseIntruction": case_instruction,
                        "bh": bh,
                        "txm": _txm_value,
                    },
                    "responseInfo": (
                        json.loads(response) if response else None
                    ),
                    "errorInfo": (
                        {"message": error_info} if error_info else None
                    ),
                }
            )

        return {"success": True, "data": formatted_calls}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"获取调用日志失败: {str(e)}")


@router.delete("/deleteLetterCall/{bh}")
async def delete_letter_call_record(bh: str, db: Session = Depends(get_db)):
    """
    根据信访件编号删除来信件API调用记录。
    """
    try:
        if db is not None:
            # 使用数据库删除
            record = (
                db.query(LaixinRecord)
                .filter(LaixinRecord.bh == bh, LaixinRecord.is_delete == 0)
                .first()
            )
            if not record:
                raise HTTPException(status_code=404, detail="记录未找到或已被删除")

            record.is_delete = 1  # 逻辑删除
            db.commit()
        else:
            # 使用存储适配器删除
            storage = get_storage_adapter()
            success = storage.delete_laixin_record(bh)
            if not success:
                raise HTTPException(status_code=404, detail="记录未找到或已被删除")
        
        return {"success": True, "message": f"记录 {bh} 已成功逻辑删除"}
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"删除记录失败: {str(e)}")


@router.delete("/batchDeleteLetterCalls")
async def batch_delete_letter_call_records(request: Dict[str, Any], db: Session = Depends(get_db)):
    """
    批量删除来信件API调用记录。
    """
    try:
        bhs = request.get("bhs", [])
        if not bhs:
            raise HTTPException(status_code=400, detail="请提供要删除的信访件编号列表")

        if db is not None:
            # 使用数据库批量删除
            records = (
                db.query(LaixinRecord)
                .filter(LaixinRecord.bh.in_(bhs), LaixinRecord.is_delete == 0)
                .all()
            )
            
            if not records:
                raise HTTPException(status_code=404, detail="未找到要删除的记录")

            # 执行逻辑删除
            deleted_count = 0
            for record in records:
                record.is_delete = 1
                deleted_count += 1

            db.commit()
        else:
            # 使用存储适配器批量删除
            storage = get_storage_adapter()
            deleted_count = storage.batch_delete_laixin_records(bhs)
            
            if deleted_count == 0:
                raise HTTPException(status_code=404, detail="未找到要删除的记录")
        
        return {
            "success": True, 
            "message": f"成功删除 {deleted_count} 条记录",
            "deleted_count": deleted_count
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=f"批量删除记录失败: {str(e)}")


@router.get("/performance")
async def get_performance_metrics(db: Session = Depends(get_db)):
    """获取来信件性能监控指标"""
    try:
        if db is not None:
            # 使用数据库查询统计
            processed_count = (
                db.query(func.count(LaixinRecord.id))
                .filter(LaixinRecord.is_delete == 0)
                .scalar()
                or 0
            )
            successful_count = (
                db.query(func.count(LaixinRecord.id))
                .filter(LaixinRecord.is_delete == 0, LaixinRecord.status == "成功")
                .scalar()
                or 0
            )
            failed_count = (
                db.query(func.count(LaixinRecord.id))
                .filter(LaixinRecord.is_delete == 0, LaixinRecord.status == "失败")
                .scalar()
                or 0
            )
        else:
            # 使用存储适配器查询统计
            storage = get_storage_adapter()
            stats = storage.get_laixin_stats()
            processed_count = stats['processed_count']
            successful_count = stats['successful_count']
            failed_count = stats['failed_count']

        return {
            "processed_count": processed_count,
            "successful_count": successful_count,
            "failed_count": failed_count,
            "active_connections": (
                len(thread_pool._threads) if hasattr(thread_pool, "_threads") else 0
            ),
        }
    except Exception as e:
        raise HTTPException(status_code=500, detail=str(e))
